package com.kexio.core.security.service.impl;

import com.kexio.core.security.context.UserContext;
import com.kexio.core.security.context.UserContextHolder;
import com.kexio.core.security.jwt.JwtTokenValidator;
import com.kexio.core.security.service.UserContextService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 默认用户上下文服务实现
 *
 * @author Kexio Team
 * @since 1.0.0
 */
public class DefaultUserContextService implements UserContextService {

    private static final Logger log = LoggerFactory.getLogger(DefaultUserContextService.class);

    @Autowired(required = false)
    private JwtTokenValidator jwtTokenValidator;

    @Override
    public boolean initUserContext(String accessToken) {
        if (accessToken == null || accessToken.trim().isEmpty()) {
            log.debug("访问令牌为空，无法初始化用户上下文");
            return false;
        }

        if (jwtTokenValidator == null) {
            log.warn("JWT令牌验证器未配置，无法初始化用户上下文");
            return false;
        }

        try {
            // 验证并解析令牌
            UserContext userContext = jwtTokenValidator.validateAndExtract(accessToken);
            if (userContext == null) {
                log.debug("无效的访问令牌，无法初始化用户上下文");
                return false;
            }

            // 设置到ThreadLocal
            UserContextHolder.setContext(userContext);
            log.debug("成功初始化用户上下文: userId={}, username={}", 
                    userContext.getUserId(), userContext.getUsername());
            return true;
        } catch (Exception e) {
            log.warn("初始化用户上下文失败: {}", e.getMessage());
            return false;
        }
    }

    @Override
    public UserContext loadUserContext(Long userId) {
        // TODO: 实际应用中应该从数据库或缓存中加载用户信息
        // 这里提供一个基础实现，需要业务系统覆盖
        
        log.warn("默认实现：loadUserContext(userId={}) 需要业务系统提供具体实现", userId);
        
        // 返回一个基础的用户上下文
        return UserContext.builder()
                .userId(userId)
                .username("user_" + userId)
                .nickname("用户" + userId)
                .tenantId(1L)
                .build();
    }

    @Override
    public UserContext loadUserContext(String username) {
        // TODO: 实际应用中应该从数据库或缓存中加载用户信息
        // 这里提供一个基础实现，需要业务系统覆盖
        
        log.warn("默认实现：loadUserContext(username={}) 需要业务系统提供具体实现", username);
        
        // 返回一个基础的用户上下文
        return UserContext.builder()
                .userId(1L)
                .username(username)
                .nickname(username)
                .tenantId(1L)
                .build();
    }

    @Override
    public boolean refreshUserContext() {
        UserContext currentContext = UserContextHolder.getContext();
        if (currentContext == null) {
            log.debug("当前没有用户上下文，无需刷新");
            return false;
        }

        try {
            // 重新加载用户信息
            UserContext refreshedContext = loadUserContext(currentContext.getUserId());
            if (refreshedContext == null) {
                log.warn("刷新用户上下文失败，无法加载用户信息: userId={}", currentContext.getUserId());
                return false;
            }

            // 保留一些原有信息
            refreshedContext.setLoginTime(currentContext.getLoginTime());
            refreshedContext.setLoginIp(currentContext.getLoginIp());
            refreshedContext.setSessionId(currentContext.getSessionId());

            // 更新上下文
            UserContextHolder.setContext(refreshedContext);
            log.debug("成功刷新用户上下文: userId={}", refreshedContext.getUserId());
            return true;
        } catch (Exception e) {
            log.error("刷新用户上下文失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public void clearUserContext() {
        UserContext context = UserContextHolder.getContext();
        if (context != null) {
            log.debug("清除用户上下文: userId={}, username={}", 
                    context.getUserId(), context.getUsername());
        }
        UserContextHolder.clear();
    }

    @Override
    public boolean isAuthenticated() {
        UserContext context = UserContextHolder.getContext();
        return context != null && context.getUserId() != null;
    }

    @Override
    public void updateUserContext(UserContext userContext) {
        if (userContext == null) {
            clearUserContext();
            return;
        }

        UserContextHolder.setContext(userContext);
        log.debug("更新用户上下文: userId={}, username={}", 
                userContext.getUserId(), userContext.getUsername());
    }

    @Override
    public void mergeUserContext(UserContext additionalContext) {
        if (additionalContext == null) {
            return;
        }

        UserContext currentContext = UserContextHolder.getContext();
        if (currentContext == null) {
            updateUserContext(additionalContext);
            return;
        }

        // 合并上下文信息，优先使用现有信息
        UserContext mergedContext = UserContext.builder()
                .userId(currentContext.getUserId() != null ? currentContext.getUserId() : additionalContext.getUserId())
                .username(currentContext.getUsername() != null ? currentContext.getUsername() : additionalContext.getUsername())
                .nickname(currentContext.getNickname() != null ? currentContext.getNickname() : additionalContext.getNickname())
                .email(currentContext.getEmail() != null ? currentContext.getEmail() : additionalContext.getEmail())
                .phone(currentContext.getPhone() != null ? currentContext.getPhone() : additionalContext.getPhone())
                .avatar(currentContext.getAvatar() != null ? currentContext.getAvatar() : additionalContext.getAvatar())
                .tenantId(currentContext.getTenantId() != null ? currentContext.getTenantId() : additionalContext.getTenantId())
                .tenantName(currentContext.getTenantName() != null ? currentContext.getTenantName() : additionalContext.getTenantName())
                .deptId(currentContext.getDeptId() != null ? currentContext.getDeptId() : additionalContext.getDeptId())
                .deptName(currentContext.getDeptName() != null ? currentContext.getDeptName() : additionalContext.getDeptName())
                .roles(currentContext.getRoles() != null && !currentContext.getRoles().isEmpty() ? 
                       currentContext.getRoles() : additionalContext.getRoles())
                .permissions(currentContext.getPermissions() != null && !currentContext.getPermissions().isEmpty() ? 
                           currentContext.getPermissions() : additionalContext.getPermissions())
                .loginTime(currentContext.getLoginTime() != null ? currentContext.getLoginTime() : additionalContext.getLoginTime())
                .loginIp(currentContext.getLoginIp() != null ? currentContext.getLoginIp() : additionalContext.getLoginIp())
                .sessionId(currentContext.getSessionId() != null ? currentContext.getSessionId() : additionalContext.getSessionId())
                .isAdmin(currentContext.getIsAdmin() != null ? currentContext.getIsAdmin() : additionalContext.getIsAdmin())
                .attributes(currentContext.getAttributes() != null && !currentContext.getAttributes().isEmpty() ? 
                          currentContext.getAttributes() : additionalContext.getAttributes())
                .build();

        updateUserContext(mergedContext);
        log.debug("合并用户上下文完成: userId={}", mergedContext.getUserId());
    }

    /**
     * 设置JWT令牌验证器
     * 
     * @param jwtTokenValidator JWT令牌验证器
     */
    public void setJwtTokenValidator(JwtTokenValidator jwtTokenValidator) {
        this.jwtTokenValidator = jwtTokenValidator;
    }
}
